package atack.tesis.kelluntekun.ui.componentes;

import java.io.Serializable;
import org.vaadin.aceeditor.gwt.ace.AceMode;

import atack.tesis.kelluntekun.domain.Usuario;
import atack.tesis.kelluntekun.domain.enums.Pais;
import atack.tesis.kelluntekun.domain.enums.Sexo;
import atack.tesis.kelluntekun.enums.GenCaption;
import atack.tesis.kelluntekun.ui.componentes.utils.UiUtils;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.validator.EmailValidator;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/**
 * @author marza
 *
 */
public class UserFormView extends Window implements Serializable{
	private static final long serialVersionUID = 1L;
	
	private VerticalLayout vlyMain;
	private HorizontalLayout hlyButtons;
	
	private TextField tfMail;
	private TextField tfNick;
	private PasswordField pfPassword;
	private PasswordField pfConfirmPassword;
//	private DateField dfFechaNacimiento;
	
	private NativeSelect nsPaisOrigen;
	private NativeSelect nsSexo;
	private NativeSelect nsLenguajePrincipal;
	
	private Button btEnviar;
	private Button btCancelar;
	
	public UserFormView(){
		this.setModal(true);
		this.setWidth("240px");
//		this.setHeight("380px");
		this.setModal(true);
		this.setCaption("Registrar Usuario");
		this.setResizable(false);
		
		vlyMain = new VerticalLayout();
		vlyMain.setSizeFull();
		vlyMain.setSpacing(false);
		vlyMain.setMargin(true, true, false, true);
		
		buildFields();
		addFieldsValidators();
		addListeners();
		
		buildButtons();
		vlyMain.addComponent(hlyButtons);
		vlyMain.setComponentAlignment(hlyButtons, Alignment.MIDDLE_RIGHT);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "25px"));
		tfMail.focus();
		this.setContent(vlyMain);
	}
	
	/**
	 * Construye los campos necesarios para el registro de Usuarios.
	 */
	private void buildFields(){
		
		tfMail = new TextField("Mail:");
		tfMail.setWidth("200px");
		tfMail.setImmediate(true);
		tfMail.setNullRepresentation("");
		tfMail.setRequired(true);
		vlyMain.addComponent(tfMail);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "5px"));
		
		tfNick = new TextField("Nick:");
		tfNick.setWidth("200px");
		tfNick.setImmediate(true);
		tfNick.setNullRepresentation("");
		tfNick.setRequired(true);
		tfNick.setMaxLength(20);
		vlyMain.addComponent(tfNick);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "5px"));
		
		pfPassword = new PasswordField("Password:");
		pfPassword.setWidth("200px");
		pfPassword.setImmediate(true);
		pfPassword.setNullRepresentation("");
		pfPassword.setRequired(true);
		vlyMain.addComponent(pfPassword);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "5px"));
		
		pfConfirmPassword = new PasswordField("Confirmar Password:");
		pfConfirmPassword.setWidth("200px");
		pfConfirmPassword.setImmediate(true);
		pfConfirmPassword.setNullRepresentation("");
		pfConfirmPassword.setRequired(true);
		vlyMain.addComponent(pfConfirmPassword);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "5px"));
		
		nsSexo=new NativeSelect("Sexo: ");
		for (Sexo sexo:Sexo.values()){
			nsSexo.addItem(sexo);
			
		}
		nsSexo.setImmediate(true);
		vlyMain.addComponent(nsSexo);
		
		nsPaisOrigen= new NativeSelect("País de Origen");
		nsPaisOrigen.setWidth("200px");
		for (Pais pais:Pais.values()){
			nsPaisOrigen.addItem(pais);
			
		}
		nsPaisOrigen.setImmediate(true);
		vlyMain.addComponent(nsPaisOrigen);
		
		nsLenguajePrincipal = new NativeSelect("Lenguaje Principal: ");
		for(AceMode mode:AceMode.values()){
			nsLenguajePrincipal.addItem(mode);
		}
		nsLenguajePrincipal.setNullSelectionAllowed(false);
		nsLenguajePrincipal.setImmediate(true);
		vlyMain.addComponent(nsLenguajePrincipal);
		
		vlyMain.addComponent(UiUtils.getLbSpace("10px", "25px"));
		
	}
	
	/**
	 * Agrega los validadores pertinentes a los campos que lo necesiten.
	 */
	private void addFieldsValidators(){
		
		tfMail.addValidator(new EmailValidator("Debes usar un Email válido"));
		tfNick.addValidator(new StringLengthValidator("Debes usar entre cuatro y 20 caracteres.", 4, 20,false));
		tfNick.addValidator(new RegexpValidator("[a-zA-Z0-9]{4,20}", true, "Debes ingresar solo caracteres y números"));
//		"^[a-zA-Z0-9_-]{2,15}@[a-zA-Z0-9_-]{2,15}.[a-zA-Z]{2,4}(.[a-zA-Z]{2,4})?$"
		pfPassword.addValidator(new StringLengthValidator("Debes usar como mínimo seis caracteres.", 6, 30,false));
		
	}
	
	/**
	 * Agrega el Listener para la confirmación de password.
	 */
	private void addListeners(){
		
		this.pfConfirmPassword.addListener(new  Property.ValueChangeListener(){
			private static final long serialVersionUID = 1L;

			public void valueChange(ValueChangeEvent event){
				if(pfConfirmPassword.getValue()!=null){
					if(pfPassword.isValid()&&
							!pfConfirmPassword.getValue().toString().equals(pfPassword.getValue().toString())){
						getWindow().showNotification("<center>Las passwords no coinciden</center>", null, Notification.TYPE_WARNING_MESSAGE, true);
						pfConfirmPassword.setValue("");
						pfConfirmPassword.focus();
					}
				}
				else{
					getWindow().showNotification("<center>Debes confirmar tu password</center>", null, Notification.TYPE_WARNING_MESSAGE, true);
					pfConfirmPassword.setValue(null);
					pfConfirmPassword.focus();
				}
			}
		});
	}
	
	/**
	 * Construye los botones para confirmar y cancelar la creación de usuarios
	 */
	private void buildButtons(){
		hlyButtons= new HorizontalLayout();
		hlyButtons.setSpacing(true);
		hlyButtons.setMargin(false);
		
		btCancelar = new Button(GenCaption.CANCELAR);
		btCancelar.setDescription("Cancelar la creación del nuevo usuario.");
		btCancelar.setWidth("80px");
		hlyButtons.addComponent(btCancelar);
		
		
		btEnviar= new Button("Enviar");
		btEnviar.setDescription("Enviar datos y crear Usuario.");
		btEnviar.setWidth("100px");
		hlyButtons.addComponent(btEnviar);
	}
	
	/**
	 * Verifica que los valores ingresados en los campos del formulario sean validos.
	 * @return true si los campos han sido llenados correctamente, false de lo contrario
	 */
	public Boolean isValid(){
		return (this.tfMail.isValid()&&this.tfNick.isValid()&&
				this.pfPassword.isValid()&&this.pfConfirmPassword.getValue().toString().equals(pfPassword.getValue().toString()));
	}
	
	/**
	 * Retorna un objeto 'Usuario' con los valores ingresados en los campos.
	 * @return
	 */
	public Usuario getUsuario(){
		return (new Usuario(
				tfMail.getValue().toString(), 
				pfPassword.getValue().toString(), 
				tfNick.getValue().toString(),
				(AceMode) nsLenguajePrincipal.getValue(),
				(Sexo) nsSexo.getValue(),
				(Pais) nsPaisOrigen.getValue()));
	}

	/**
	 * @return the btEnviar
	 */
	public Button getBtEnviar() {
		return btEnviar;
	}

	/**
	 * @return the btCancelar
	 */
	public Button getBtCancelar() {
		return btCancelar;
	}
	
	private String debugLine(){
		return"#################################################################################>>> ";
	}
	
}
